<template>
  <el-drawer
    :visible.sync="dialogVisible"
    :title="title"
    size="90%"
    direction="rtl"
    :before-close="handleClose"
    :wrapper-closable="false"
  >
    <div v-loading="loading" class="ai-embed-chat-container">
      <el-row :gutter="20" style="height: calc(100vh - 120px);">
        <!-- 左侧：AI对话区域 -->
        <el-col :span="leftSpan">
          <div class="chat-panel">
            <!-- 预设问题卡片区域（slot） -->
            <div v-if="$slots['question-cards'] || suggestedQuestions.length > 0" class="question-cards-section">
              <slot name="question-cards" :send-question="sendPredefinedQuestion">
                <!-- 默认问题卡片 -->
                <div class="suggested-questions">
                  <div
                    v-for="(q, index) in suggestedQuestions"
                    :key="index"
                    class="question-card"
                    @click="sendPredefinedQuestion(q.question)"
                  >
                    <i :class="q.icon" :style="{ color: q.color }" />
                    <span>{{ q.title }}</span>
                  </div>
                </div>
              </slot>
            </div>

            <!-- 消息列表 -->
            <div ref="messageList" class="message-list">
              <div v-for="(msg, index) in chatMessages" :key="index" class="message-item" :class="msg.role">
                <div class="message-content">
                  <div v-if="msg.role === 'user'" class="user-message">
                    {{ msg.content }}
                  </div>
                  <div v-else class="assistant-message">
                    <div v-html="renderMarkdown(msg.content)" />
                  </div>
                </div>
              </div>
              <div v-if="isStreaming" class="streaming-indicator">
                <i class="el-icon-loading" /> AI正在思考...
              </div>
            </div>

            <!-- 输入区域 -->
            <div class="input-area">
              <el-input
                v-model="userInput"
                type="textarea"
                :rows="3"
                :placeholder="placeholder"
                :disabled="isStreaming"
                @keydown.ctrl.enter.native="handleSend"
              />
              <div class="input-actions">
                <el-button
                  v-if="isStreaming"
                  size="small"
                  type="warning"
                  icon="el-icon-close"
                  @click="cancelRequest"
                >
                  取消
                </el-button>
                <el-button
                  type="primary"
                  size="small"
                  icon="el-icon-s-promotion"
                  :loading="isStreaming"
                  :disabled="!userInput.trim() || isStreaming"
                  style="background-color: #1EB7E6; border-color: #1EB7E6;"
                  @click="handleSend"
                >
                  发送 (Ctrl+Enter)
                </el-button>
              </div>
            </div>
          </div>
        </el-col>

        <!-- 右侧：自定义内容区域（slot） -->
        <el-col v-if="$slots['right-panel']" :span="rightSpan">
          <div class="right-panel">
            <slot name="right-panel" :parsed-data="parsedData" :messages="chatMessages" />
          </div>
        </el-col>
      </el-row>
      <!-- Footer 底部按钮 -->
      <div class="drawer-footer">
        <slot name="footer" :close="handleClose">
          <el-button @click="handleClose">关闭</el-button>
        </slot>
      </div>
    </div>
  </el-drawer>
</template>

<script>
import { marked } from 'marked'
import { getToken } from '@/utils/auth'

export default {
  name: 'AIEmbedChat',
  props: {
    // 是否显示对话框
    visible: {
      type: Boolean,
      default: false
    },
    // 对话框标题
    title: {
      type: String,
      default: 'AI智能对话'
    },
    // API URL
    apiUrl: {
      type: String,
      required: true
    },
    // 业务上下文数据（会发送给后端）
    contextData: {
      type: Object,
      default: () => ({})
    },
    // 预设问题列表
    suggestedQuestions: {
      type: Array,
      default: () => []
    },
    // 输入框占位符
    placeholder: {
      type: String,
      default: '请输入您的问题...'
    },
    // AI引擎
    engine: {
      type: String,
      default: 'claude-sonnet-4.5'
    },
    // 是否自动解析JSON
    autoParseJson: {
      type: Boolean,
      default: false
    },
    // 左侧面板宽度
    leftSpan: {
      type: Number,
      default: 12
    },
    // 右侧面板宽度
    rightSpan: {
      type: Number,
      default: 12
    },
    // 处理函数名称（用于区分不同业务）
    handlerName: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      dialogVisible: false,
      loading: false,
      isStreaming: false,
      userInput: '',
      chatMessages: [],
      parsedData: null,
      controller: null
    }
  },
  computed: {
    headers() {
      return {
        'Authorization': getToken(),
        'PTOKEN': this.$store.getters.projectId,
        'Content-Type': 'application/json'
      }
    }
  },
  watch: {
    visible(val) {
      this.dialogVisible = val
      if (val) {
        this.onDialogOpen()
      }
    },
    dialogVisible(val) {
      this.$emit('update:visible', val)
    }
  },
  methods: {
    // 对话框打开时的回调
    onDialogOpen() {
      this.$emit('dialog-opened')
      this.$nextTick(() => {
        this.scrollToBottom()
      })
    },

    // 发送预设问题
    sendPredefinedQuestion(question) {
      this.userInput = question
      this.handleSend()
    },

    // 发送消息
    async handleSend() {
      if (!this.userInput.trim() || this.isStreaming) {
        return
      }

      const userMessage = this.userInput.trim()
      this.userInput = ''

      // 添加用户消息
      this.chatMessages.push({
        role: 'user',
        content: userMessage,
        timestamp: new Date()
      })

      // 添加AI消息占位
      const assistantIndex = this.chatMessages.length
      this.chatMessages.push({
        role: 'assistant',
        content: '',
        timestamp: new Date()
      })

      this.$nextTick(() => this.scrollToBottom())

      // 开始流式请求
      this.isStreaming = true
      this.controller = new AbortController()

      try {
        const response = await fetch(`${process.env.VUE_APP_BASE_API}${this.apiUrl}`, {
          method: 'POST',
          headers: this.headers,
          body: JSON.stringify({
            handler_name: this.handlerName,
            user_message: userMessage,
            engine: this.engine,
            context_data: this.contextData,
            chat_history: this.chatMessages.slice(0, -1) // 不包含当前占位消息
          }),
          signal: this.controller.signal
        })

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`)
        }

        const reader = response.body.getReader()
        const decoder = new TextDecoder()
        let fullText = ''
        let done = false

        while (!done) {
          const result = await reader.read()
          done = result.done

          if (!done) {
            const chunk = decoder.decode(result.value, { stream: true })
            fullText += chunk

            // 更新消息内容
            this.$set(this.chatMessages[assistantIndex], 'content', fullText)
            this.$nextTick(() => this.scrollToBottom())
          }
        }

        // 流式响应完成，触发回调
        this.$emit('message-completed', {
          role: 'assistant',
          content: fullText
        })

        // 如果开启自动解析JSON
        if (this.autoParseJson) {
          this.tryParseJson(fullText)
        }
      } catch (error) {
        if (error.name === 'AbortError') {
          this.$message.info('已取消请求')
          this.$set(this.chatMessages[assistantIndex], 'content', '[已取消]')
        } else {
          console.error('AI对话错误:', error)
          this.$message.error('AI对话失败: ' + error.message)
          this.$set(this.chatMessages[assistantIndex], 'content', `[错误: ${error.message}]`)
        }
      } finally {
        this.isStreaming = false
        this.controller = null
      }
    },

    // 取消请求
    cancelRequest() {
      if (this.controller) {
        this.controller.abort()
        this.controller = null
      }
    },

    // 尝试解析JSON
    tryParseJson(text) {
      try {
        // 尝试提取JSON代码块
        const jsonMatch = text.match(/```json\n([\s\S]*?)\n```/) ||
                         text.match(/```\n([\s\S]*?)\n```/)

        if (jsonMatch) {
          const jsonData = JSON.parse(jsonMatch[1])
          this.parsedData = jsonData
          this.$emit('json-parsed', jsonData)
          return
        }

        // 尝试直接解析整个文本
        const jsonData = JSON.parse(text)
        this.parsedData = jsonData
        this.$emit('json-parsed', jsonData)
      } catch (e) {
        // 不是有效的JSON，忽略
        console.debug('无法解析JSON:', e)
      }
    },

    // Markdown渲染
    renderMarkdown(text) {
      if (!text) return ''
      try {
        return marked(text)
      } catch (e) {
        return text
      }
    },

    // 滚动到底部
    scrollToBottom() {
      if (this.$refs.messageList) {
        this.$nextTick(() => {
          this.$refs.messageList.scrollTop = this.$refs.messageList.scrollHeight
        })
      }
    },

    // 关闭对话框
    handleClose() {
      if (this.isStreaming) {
        this.$confirm('对话正在进行中，确定要关闭吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.cancelRequest()
          this.dialogVisible = false
        }).catch(() => {})
      } else {
        this.dialogVisible = false
      }
    },

    // 清空对话历史
    clearHistory() {
      this.$confirm('确定要清空对话历史吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.chatMessages = []
        this.parsedData = null
        this.$message.success('对话历史已清空')
      }).catch(() => {})
    },

    // 导出对话
    exportChat() {
      const chatText = this.chatMessages.map(msg => {
        return `${msg.role === 'user' ? '用户' : 'AI'}: ${msg.content}\n\n`
      }).join('')

      const blob = new Blob([chatText], { type: 'text/plain;charset=utf-8' })
      const url = URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = url
      link.download = `AI对话_${new Date().toISOString().slice(0, 10)}.txt`
      link.click()
      URL.revokeObjectURL(url)

      this.$message.success('对话已导出')
    }
  }
}
</script>

<style scoped lang="scss">
.ai-embed-chat-container {
  height: 100%;

  ::v-deep .el-col {
    height: 100%;
  }

  .chat-panel {
    display: flex;
    flex-direction: column;
    height: 100%;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    background: #fff;
  }

  .question-cards-section {
    flex-shrink: 0; // 防止被压缩
    padding: 15px;
    border-bottom: 1px solid #e4e7ed;
    max-height: 200px;
    overflow-y: auto;
  }

  .suggested-questions {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 10px;
  }

  .question-card {
    padding: 12px 15px;
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.3s;
    display: flex;
    align-items: center;
    gap: 8px;
    background: #f5f7fa;

    i {
      font-size: 18px;
    }

    span {
      font-size: 13px;
      color: #606266;
    }

    &:hover {
      border-color: #1EB7E6;
      background: #ecf5ff;
      transform: translateY(-2px);
      box-shadow: 0 2px 8px rgba(30, 183, 230, 0.2);
    }
  }

  .message-list {
    flex: 1 1 0; // flex-grow: 1, flex-shrink: 1, flex-basis: 0
    min-height: 0; // 关键：让 flex 子元素能够缩小到比内容小
    padding: 15px;
    overflow-y: auto; // 内容超出时滚动
    overflow-x: hidden;
    background: #f5f7fa;
  }

  .message-item {
    margin-bottom: 15px;
    animation: fadeIn 0.3s;

    &.user {
      display: flex;
      justify-content: flex-end;

      .message-content {
        max-width: 70%;
      }

      .user-message {
        padding: 10px 15px;
        background: #1EB7E6;
        color: white;
        border-radius: 8px 8px 0 8px;
        word-break: break-word;
      }
    }

    &.assistant {
      display: flex;
      justify-content: flex-start;

      .message-content {
        max-width: 85%;
      }

      .assistant-message {
        padding: 10px 15px;
        background: white;
        border: 1px solid #e4e7ed;
        border-radius: 8px 8px 8px 0;
        word-break: break-word;

        ::v-deep {
          h1, h2, h3 { margin: 10px 0 5px 0; }
          p { margin: 5px 0; }
          code {
            background: #f5f7fa;
            padding: 2px 6px;
            border-radius: 3px;
            font-family: monospace;
          }
          pre {
            background: #f5f7fa;
            padding: 10px;
            border-radius: 4px;
            overflow-x: auto;
            code {
              background: none;
              padding: 0;
            }
          }
          ul, ol { padding-left: 20px; }
          blockquote {
            border-left: 3px solid #1EB7E6;
            padding-left: 10px;
            margin: 10px 0;
            color: #606266;
          }
        }
      }
    }
  }

  .streaming-indicator {
    text-align: center;
    padding: 10px;
    color: #909399;
    font-size: 13px;

    i {
      margin-right: 5px;
    }
  }

  .input-area {
    flex-shrink: 0; // 防止被压缩
    padding: 15px;
    border-top: 1px solid #e4e7ed;
    background: white;

    .input-actions {
      margin-top: 10px;
      display: flex;
      justify-content: flex-end;
      gap: 10px;
    }
  }

  .right-panel {
    height: 100%;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    background: #fff;
    padding: 15px;
    overflow-y: auto;
  }

  .drawer-footer {
    padding: 15px 20px;
    border-top: 1px solid #e4e7ed;
    background: #fff;
    text-align: right;
    margin-top: 15px;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
